using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;


namespace YATC
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public class EnterDialog : GameScene
    {

        private KeyboardState oldKeyboardState;
        private KeyboardState currentKeyboardState;
        private string textString;
        private Rectangle limite;
        private SpriteFont font;

        public EnterDialog(Game game, SpriteFont font)
            : base(game)
        {
            limite = new Rectangle(0,0,222,20);
            textString = "";
            oldKeyboardState = Keyboard.GetState();
            this.font = font;
        }

        public static string ConvertKeyToChar(Keys key, bool shift)
        {
            switch (key)
            {
                case Keys.Space: return " ";

                // Escape Sequences 
                case Keys.Enter: return "\n";                         // Create a new line 
                case Keys.Tab: return "\t";                           // Tab to the right 

                // D-Numerics (strip above the alphabet) 
                case Keys.D0: return !shift ? ")" : "0";
                case Keys.D1: return !shift ? "!" : "1";
                case Keys.D2: return !shift ? "@" : "2";
                case Keys.D3: return !shift ? "#" : "3";
                case Keys.D4: return !shift ? "$" : "4";
                case Keys.D5: return !shift ? "%" : "5";
                case Keys.D6: return !shift ? "^" : "6";
                case Keys.D7: return !shift ? "&" : "7";
                case Keys.D8: return !shift ? "*" : "8";
                case Keys.D9: return !shift ? "(" : "9";

                // Numpad 
                case Keys.NumPad0: return "0";
                case Keys.NumPad1: return "1";
                case Keys.NumPad2: return "2";
                case Keys.NumPad3: return "3";
                case Keys.NumPad4: return "4";
                case Keys.NumPad5: return "5";
                case Keys.NumPad6: return "6";
                case Keys.NumPad7: return "7";
                case Keys.NumPad8: return "8";
                case Keys.NumPad9: return "9";
                case Keys.Add: return "+";
                case Keys.Subtract: return "-";
                case Keys.Multiply: return "*";
                case Keys.Divide: return "/";
                case Keys.Decimal: return ".";

                // Alphabet 
                case Keys.A: return shift ? "A" : "a";
                case Keys.B: return shift ? "B" : "b";
                case Keys.C: return shift ? "C" : "c";
                case Keys.D: return shift ? "D" : "d";
                case Keys.E: return shift ? "E" : "e";
                case Keys.F: return shift ? "F" : "f";
                case Keys.G: return shift ? "G" : "g";
                case Keys.H: return shift ? "H" : "h";
                case Keys.I: return shift ? "I" : "i";
                case Keys.J: return shift ? "J" : "j";
                case Keys.K: return shift ? "K" : "k";
                case Keys.L: return shift ? "L" : "l";
                case Keys.M: return shift ? "M" : "m";
                case Keys.N: return shift ? "N" : "n";
                case Keys.O: return shift ? "O" : "o";
                case Keys.P: return shift ? "P" : "p";
                case Keys.Q: return shift ? "Q" : "q";
                case Keys.R: return shift ? "R" : "r";
                case Keys.S: return shift ? "S" : "s";
                case Keys.T: return shift ? "T" : "t";
                case Keys.U: return shift ? "U" : "u";
                case Keys.V: return shift ? "V" : "v";
                case Keys.W: return shift ? "W" : "w";
                case Keys.X: return shift ? "X" : "x";
                case Keys.Y: return shift ? "Y" : "y";
                case Keys.Z: return shift ? "Z" : "z";

                // Oem 
                case Keys.OemOpenBrackets: return !shift ? "{" : "[";
                case Keys.OemCloseBrackets: return !shift ? "}" : "]";
                case Keys.OemComma: return !shift ? "<" : ",";
                case Keys.OemPeriod: return !shift ? ">" : ".";
                case Keys.OemMinus: return !shift ? "_" : "-";
                case Keys.OemPlus: return !shift ? "+" : "=";
                case Keys.OemQuestion: return !shift ? "?" : "/";
                case Keys.OemSemicolon: return !shift ? ":" : ";";
                case Keys.OemQuotes: return !shift ? "\"" : "'";
                case Keys.OemPipe: return !shift ? "|" : "\\";
                case Keys.OemTilde: return !shift ? "~" : "`";
            }

            return string.Empty;
        } 


        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {
            UpdateInput();

            base.Update(gameTime);
        }
        private void UpdateInput()
        {
           

            oldKeyboardState = currentKeyboardState;
            currentKeyboardState = Keyboard.GetState();

            Keys[] pressedKeys = currentKeyboardState.GetPressedKeys();


            foreach (Keys key in pressedKeys)
            {
                if (oldKeyboardState.IsKeyUp(key))
                {
                    if (key == Keys.Back && textString.Length > 0)
                        textString = textString.Remove(textString.Length - 1, 1);
                    else if (StopWriting())
                        return;
                    else
                        if (key == Keys.Space)
                            textString = textString.Insert(textString.Length, " ");
                        else
                            if (key != Keys.Enter)
                                textString += ConvertKeyToChar(key,
                                                               (Keyboard.GetState().IsKeyDown(Keys.LeftShift) ||
                                                                Keyboard.GetState().IsKeyDown(Keys.RightShift))
                                                                   ? true
                                                                   : false);
                }
            }
        }

        private bool StopWriting()
        {
            char[] str = textString.ToCharArray();
 
            string line = string.Empty;

            foreach (char s in str)
            {
                if (font.MeasureString(s + line).Length() > limite.Width)
                    return true;
                line += s;

            }

            return false;
        }
        
        public string Text
        {
            get { return textString; }
        }
        public override void Show()
        {
            textString = String.Empty;
            base.Show();
        }
    }
}